/* what is this ? 
   NAME    本文件组织一个下载器（客户端）

   DESCRIPTION
   (1)WORKFLOW
   0       下载器与服务器建立连接
   1       下载器向服务器发送文件名，并在本地创建同名文件接收数据
   2       下载器接收数据
   3       下载器等待下一次输入文件名或等待“EXIT”指令退出
   4       关闭连接
   */

/* header file */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/types.h>
#include "socket.h"

/* macro definition */
#define PAGESIZE    4096
/* type declaration  */
typedef int data_t;


/* variable definition  */


/* function declaration */

int main(int argc, char** argv)
{
    if(argc != 3){
        printf("client.c\\main()\\: invalid argument count\n\n");
        exit(1);
    };
    
    // 与服务器建立连接
    int clientfd = open_clientfd(argv[1], argv[2]);

    char buffer[PAGESIZE];
    while(1){
        // stdin输入文件名
        puts("client.c\\main():"
             "Pls enter the file path");
        int read_count = read(STDIN_FILENO, buffer, PAGESIZE);
        buffer[read_count-1] ='\0'; // 避免打开的文件名是乱码

        if(strcmp(buffer, "EXIT") == 0){
        printf("client.c\\main():"
               "receive EXIT command, goodbye\n");
            break;
        } // 退出指令
        
        // 先在本地建立同名文件等待接收数据
        printf("client.c\\main():"
               "open local file %s\n",
               buffer);
        int download_filefd = open(buffer, 
                                   O_WRONLY | O_CREAT | O_TRUNC, 
                                   0664);
        puts("client.c\\main(): "
             "local file ready");
        assert(download_filefd > 0);
        
        // 向服务端发送请求下载文件信息
        send(clientfd, buffer, 
             PAGESIZE, MSG_NOSIGNAL);   // MSG_NOSIGNAL防止在写入文件时
                                          // 对端关闭造成SIGPIPE进程关闭
        puts("client.c\\main(): "
             "download request have been sent");
        
        // 开始接收文件, MSG_WAITALL防止半包问题
        puts("client.c\\main():"
             "start downloading file");
        int recv_count = recv(clientfd, buffer, 
                              PAGESIZE, 0);
        while(recv_count > 0){
            int wrcount = write(download_filefd, buffer, recv_count);
            if(wrcount != recv_count){
                printf("client.c\\main(): write to buffer error\n\n");
            };
            recv_count = recv(clientfd, buffer, PAGESIZE, MSG_DONTWAIT);//先不使用MSG_WAITALL
            if(recv_count < 0){ sleep(1);} // stupid idea
            recv_count = recv(clientfd, buffer, PAGESIZE, MSG_DONTWAIT);//先不使用MSG_WAITALL
        }
        printf("client.c\\main(): "
               "file downloaded successfully\n");
        close(download_filefd);
    }

    // clean up
    close(clientfd);

    return 0;
}


